package routines

import (
	"image"
	"image/jpeg"
	"io/ioutil"
	"log"
	"os"
	"sync"
	"time"
	"path/filepath"

	"golang.org/x/image/draw"
	"gitee.com/xieyu305/workers/channels"
	"gitee.com/xieyu305/workers/types"
)

func scaleTo(src image.Image, rect image.Rectangle, scale draw.Scaler) image.Image {
	dist := image.NewRGBA(rect)
	scale.Scale(dist, rect, src, src.Bounds(), draw.Over, nil)
	time.Sleep(1 * time.Second)
	return dist
}

func scaleWorker(group *sync.WaitGroup) {
	for sourceImage := range channels.SourceChannel {
		src := sourceImage.Image
		scaleInstant := draw.NearestNeighbor
		dr := image.Rect(0, 0, src.Bounds().Max.X/4, src.Bounds().Max.Y/4)
		var res image.Image
		res = scaleTo(src, dr, scaleInstant)
		resultImage := types.ResultImage{
			Name:  sourceImage.Name,
			Image: res,
		}
		channels.ResultChannel <- resultImage
	}
	group.Done()
}

func CreateWorkers(number int) {
	var group sync.WaitGroup
	for i := 0; i < number; i++ {
		group.Add(1)
		go scaleWorker(&group)
	}
	group.Wait()
	close(channels.ResultChannel)
}

func ReadImagesFromPath(path string) {
	allDir, err := ioutil.ReadDir(path)
	if err != nil {
		log.Fatal(err)
	}

	for _, entry := range allDir {
		fileName := entry.Name()
		extension := filepath.Ext(fileName)
		if (extension != ".jpg") && (extension != ".jpeg") {
			continue;
		}
		filePath := path + "/" + fileName
		file, fileErr := os.Open(filePath)
		if fileErr != nil {
			log.Fatal(fileErr)
		}

		img, _, err := image.Decode(file)
		if err != nil {
			log.Fatal(err)
		}
		sourceImage := types.SourceImage{
			Name:  fileName,
			Image: img,
		}
		channels.SourceChannel <- sourceImage
	}
	close(channels.SourceChannel)
}

func WriteImageToPath(path string, allComplete chan bool) {
	for resultImage := range channels.ResultChannel {
		distFile, err := os.Create(path + "/" + resultImage.Name)
		if err != nil {
			log.Fatal(err)
		}

		err = jpeg.Encode(distFile, resultImage.Image, &jpeg.Options{jpeg.DefaultQuality})
		defer distFile.Close()
		if err != nil {
			log.Fatal(err)
		}
		log.Println("successfully scale", resultImage.Name)
	}
	allComplete <- true
}
